﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Text;
using yaTDL.Extensions;
using yaTDL.Core;
using yaTDL.Core.Toodledo;
using System.Collections.ObjectModel;

namespace yaTDL.Testing
{
    public class ToodledoClientTester
    {
        ToodledoClientV2 toodledoClient = new ToodledoClientV2();


        string key = "";
        string sessionToken = null;

        string userId = "";
        string password = "";

        bool errorOccurred = false;



        public ToodledoClientTester()
        {
            toodledoClient.ErrorOccurred += new EventHandler<ErrorEventArgsV2>(toodledoClient_ErrorOccurred);
        }

        void toodledoClient_ErrorOccurred(object sender, ErrorEventArgsV2 e)
        {
            errorOccurred = true;

            Console.WriteLine(String.Format("ERROR  {0}     {1}", e.ErrorCode, e.ErrorMessage));
        }

        public void EnterCommand(string cmd)
        {
            Console.WriteLine();
            errorOccurred = false;

            if (cmd.ToLower().StartsWith("paste "))
            {
                _paste(cmd.Substring(6));
                return;
            }


            switch (cmd.ToLower())
            {
                case "all": testAll();
                    break;
                case "getsessiontoken":
                case "get sessiontoken":
                    testGetSessionToken();
                    break;
                case "getkey":
                case "get key":
                    testGetKey();
                    break;
                case "getaccountinfo":
                case "get accountinfo":
                    testGetAccountInfo();
                    break;
                case "getfolders":
                case "get folders":
                    testGetFolders();
                    break;
                case "generatesignature":
                case "generate signature":
                case "generatesig":
                case "generate sig":
                    testGenerateSignature();
                    break;
                case "addfolder":
                case "add folder":
                    testAddFolder();
                    break;
                case "updatefolder":
                case "update folder":
                    testUpdateFolder();
                    break;
                case "deletefolder":
                case "delete folder":
                    testDeleteFolder();
                    break;
                case "gettasks":
                case "get tasks":
                    testGetTasks();
                    break;
                case "deletetasks":
                case "delete tasks":
                    testDeleteTasks();
                    break;
                case "getdeletedtasks":
                case "get deleted tasks":
                    testGetDeletedTasks();
                    break;
                case "addtasks":
                case "add tasks":
                    testAddTasks();
                    break;
                case "updatetasks":
                case "update tasks":
                    testUpdateTasks();
                    break;
                case "copy sessiontoken": Clipboard.SetText(sessionToken);
                    break;
                case "copy key": Clipboard.SetText(key); Console.WriteLine("DONE");
                    break;
                case "copy userid": Clipboard.SetText(userId); Console.WriteLine("DONE");
                    break;
                case "copy password": Clipboard.SetText(password); Console.WriteLine("DONE");
                    break;
                case "set sessiontoken": sessionToken = cmd.Substring(("set sessiontoken").Length); Console.WriteLine("DONE");
                    break;
                case "set key": key = cmd.Substring(("set key").Length); Console.WriteLine("DONE");
                    break;
                case "set userid": sessionToken = cmd.Substring(("set userid").Length); Console.WriteLine("DONE");
                    break;
                case "set password": password = cmd.Substring(("set password").Length); Console.WriteLine("DONE");
                    break;
                default: Program.unknownCommand();
                    break;
            }
        }

        public void testAll()
        {
            testGenerateSignature();
            testGetSessionToken();
            testGetKey();
            testGetAccountInfo();
            testGetFolders();
            testAddFolder();
            testUpdateFolder();
            testDeleteFolder();
            testGetTasks();
            testDeleteTasks();
            testGetDeletedTasks();
        }

        private void testGenerateSignature()
        {
            Console.WriteLine("testSignature");
            Console.WriteLine();

            Console.WriteLine(toodledoClient.GenerateSignature(userId));

            Console.WriteLine();
        }

        private void testGetSessionToken()
        {
            sessionToken = null;

            Console.WriteLine("testGetSessionToken");
            Console.WriteLine();

            sessionToken = toodledoClient.GetSessionToken(userId);

            if (!String.IsNullOrEmpty(sessionToken) && !errorOccurred)
            {
                Console.WriteLine("GetSessionToken      OK");
                Console.WriteLine(sessionToken);
            }
            else
            { Console.WriteLine("GetSessionToken      FAILED"); }

            Console.WriteLine();

        }

        private void testGetKey()
        {

            Console.WriteLine("testGetKey");
            Console.WriteLine();

            if (sessionToken == null)
            {
                Console.WriteLine("No SessionToken\n\n");
                return;
            }

            ToodledoAPIKey apiKey = toodledoClient.GetKey(sessionToken, password.ToSecureString());

            key = apiKey.Key;

            Console.WriteLine(apiKey.ToString() + "\n\n");
        }

        private void testGetAccountInfo()
        {
            Console.WriteLine("GetAccountInfo");
            Console.WriteLine();

            if (String.IsNullOrEmpty(key))
            {
                Console.WriteLine("No Key");
            }
            else
            {
                ToodledoAccountInfoV2 info = toodledoClient.GetAccountInfo(key);
                if (info != null)
                    Console.Write(info.ToString());
            }

            Console.WriteLine();
        }

        private void testGetFolders()
        {
            Console.WriteLine("GetFolders");
            Console.WriteLine();

            if (String.IsNullOrEmpty(key))
            {
                Console.WriteLine("No Key");
            }
            else
            {
                Collection<Project> projects = toodledoClient.GetFolders(key);
                Console.WriteLine();

                if (projects != null && !errorOccurred)
                {
                    Console.WriteLine(String.Format("{0} Projects", projects.Count));
                    foreach (Project p in projects)
                    {
                        Console.WriteLine(p.ToShortString());
                    }
                }
            }

            Console.WriteLine();
        }

        private void testAddFolder()
        {
            Console.WriteLine("AddFolder");
            Console.WriteLine();

            if (String.IsNullOrEmpty(key))
            {
                Console.WriteLine("No Key");
            }
            else
            {
                Project p = new Project("testfolder" + DateTime.Now.ToShortDateString());
                Console.WriteLine("Adding " + p.ToString());
                bool successful = toodledoClient.AddFolder(key, p);
                if (successful)
                    Console.WriteLine("SUCCESS");
                else
                    Console.WriteLine("FAILED");
            }


        }

        private void testUpdateFolder()
        {
            Console.WriteLine("UpdateFolder");
            Console.WriteLine();

            if (String.IsNullOrEmpty(key))
            {
                Console.WriteLine("No Key");
            }
            else
            {
                Collection<Project> projects = toodledoClient.GetFolders(key);

                projects.First().Name += "_edit";

                bool successful = toodledoClient.UpdateFolder(key, projects.First());
                if (successful)
                    Console.WriteLine("SUCCESS");
                else
                    Console.WriteLine("FAILED");
            }

        }

        private void testDeleteFolder()
        {
            Console.WriteLine("DeleteFolder");
            Console.WriteLine();

            if (String.IsNullOrEmpty(key))
            {
                Console.WriteLine("No Key");
            }
            else
            {
                Collection<Project> projects = toodledoClient.GetFolders(key);

                Console.WriteLine("Deleteing Folder " + projects.Last().ToShortString());

                bool successful = toodledoClient.DeleteFolder(key, Int32.Parse(projects.Last().Id));
                if (successful)
                    Console.WriteLine("SUCCESS");
                else
                    Console.WriteLine("FAILED");
            }
        }

        private void testGetTasks()
        {
            Console.WriteLine("GetTasks");
            Console.WriteLine();

            if (String.IsNullOrEmpty(key))
            {
                Console.WriteLine("No Key");
            }
            else
            {
                Collection<Task> tasks = toodledoClient.GetTasks(key, new List<Parameter>());
                Console.WriteLine();

                if (tasks != null && !errorOccurred)
                {
                    Console.WriteLine(String.Format("{0} Tasks", tasks.Count));
                    foreach (Task t in tasks)
                    {
                        Console.WriteLine(t.ToString());
                    }
                }
            }

            Console.WriteLine();
        }

        private void testAddTasks()
        {
            Console.WriteLine("AddTasks");
            Console.WriteLine();

            if (String.IsNullOrEmpty(key))
            {
                Console.WriteLine("No Key");
            }
            else
            {
                Collection<Project> folders = toodledoClient.GetFolders(key);

                Task t1 = new Task() { Content = String.Format("TestTask {0} 1", DateTime.Now.Date.ToString()), Priority = 3, Completed = true };
                Task t2 = new Task() { Content = String.Format("TestTask {0} 2", DateTime.Now.Date.ToString()), DueDate = DateTime.Now.Date.AddDays(2) };

                List<Task> tasksToBeAdded = new List<Task>() { t1, t2 };

                Console.WriteLine("Adding Tasks");
                Console.WriteLine(t1.ToString());
                Console.WriteLine(t2.ToString());
                Console.WriteLine();

                bool successful = toodledoClient.AddTasks(key, tasksToBeAdded);
                if (successful)
                    Console.WriteLine("SUCCESS");
                else
                    Console.WriteLine("FAILED");
            }
        }

        private void testUpdateTasks()
        {
            Console.WriteLine("AddTasks");
            Console.WriteLine();

            if (_checkForKey())
            {
                Collection<Task> tasks = toodledoClient.GetTasks(key, new List<Parameter>());

                int i = tasks.Count - 1;

                Console.WriteLine(String.Format("Updating Tasks - Current Data:\n{0}\n{1}", tasks[i].ToShortString(), tasks[i - 1].ToShortString()));
                tasks[i].Content += "_edit Content+Priority";
                tasks[i].Priority = -1;
                tasks[i - 1].Content = "_edit Content+Completed+DueDate";
                tasks[i - 1].DueDate = DateTime.Now.AddDays(-7);
                tasks[i - 1].Completed = !tasks[i - 1].Completed;

                List<Task> updatedTasks = new List<Task>() { tasks[i], tasks[i - 1] };

                bool successful = toodledoClient.UpdateTasks(key, updatedTasks);

                if (successful)
                {
                    Console.WriteLine("SUCCESS");
                    Console.WriteLine(String.Format("{0}\n{1}", updatedTasks[0].ToShortString(), updatedTasks[1].ToShortString()));
                }
                else
                {
                    Console.WriteLine("FAILED");
                }

                


            }
        }

        private void testDeleteTasks()
        {
            Console.WriteLine("DeleteTasks");
            Console.WriteLine();

            if (String.IsNullOrEmpty(key))
            {
                Console.WriteLine("No Key");
            }
            else
            {
                Collection<Task> tasks = toodledoClient.GetTasks(key, new List<Parameter>());

                int i = tasks.Count - 1;

                Console.WriteLine(String.Format("Deleteing Tasks\n{0}\n{1}", tasks[i], tasks[i - 1]));

                bool successful = toodledoClient.DeleteTasks(key, new List<int>() { Int32.Parse(tasks[i].Id), Int32.Parse(tasks[i - 1].Id) });
                if (successful)
                    Console.WriteLine("SUCCESS");
                else
                    Console.WriteLine("FAILED");
            }
        }

        private void testGetDeletedTasks()
        {
            Console.WriteLine("GetDeletedTasks");
            Console.WriteLine();

            if (String.IsNullOrEmpty(key))
            {
                Console.WriteLine("No Key");
            }
            else
            {
                DateTime after = DateTime.Now.AddDays(-1);
                Collection<string> deletedTasks = toodledoClient.GetDeletedTasks(key, after);

                if (deletedTasks != null)
                {
                    Console.WriteLine(String.Format("{0} deleted Tasks since {1}", deletedTasks.Count, after));
                    foreach (string str in deletedTasks)
                    {
                        Console.WriteLine(str);
                    }
                }
                else
                { Console.WriteLine("FAILED"); }
            }
        }


        private bool _checkForKey()
        {

            if (String.IsNullOrEmpty(key))
            {
                Console.WriteLine("No Key");
                return false;
            }
            else
            {
                return true;
            }
        }

        private void _paste(string cmd)
        {
            switch (cmd.ToLower())
            {
                case "sessiontoken":
                    sessionToken = Clipboard.GetText();
                    break;
                case "key":
                    key = Clipboard.GetText();
                    break;
                case "userid":
                    userId = Clipboard.GetText();
                    break;
                case "password":
                    password = Clipboard.GetText();
                    break;
                default:
                    Program.unknownCommand();
                    return;                   
            }

            Console.WriteLine(String.Format("Pasted {0} - {1}", cmd, Clipboard.GetText()));
        }
    }
}
